package com.ruoyi.business.controller.threadpoolexecutor;

import org.jetbrains.annotations.NotNull;

import java.util.concurrent.BlockingDeque;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Wu Yuwei
 * @Description:
 * @date 2022/12/15 11:00
 */
public class CoreThreadPool implements Executor {
    /*设计此线程池的时候，核心线程是懒创建的，如果线程空闲的时候则阻塞在任务队列的take()方法，
    其实对于ThreadPoolExecutor也是类似这样实现，只是如果使用了keepAliveTime并且允许核心线程超时（allowCoreThreadTimeOut设置为true）
    则会使用BlockingQueue#poll(keepAliveTime)进行轮询代替永久阻塞。*/

    private BlockingDeque<Runnable> workQueue;
    private static final AtomicInteger COUNTER = new AtomicInteger();
    private int coreSize;
    private int threadCount = 0;

    public CoreThreadPool(int coreSize) {
        this.coreSize = coreSize;
        this.workQueue = new LinkedBlockingDeque<>();
    }

    @Override
    public void execute(@NotNull Runnable command) {
        if (++threadCount <= coreSize){
            new Worker(command).start();
        }else {
            try {
                workQueue.put(command);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
        }
    }

    private class Worker extends Thread {
        private Runnable fistTask;

        public Worker(Runnable runnable) {
            super(String.format("Worker-%d",COUNTER.getAndIncrement()));
            this.fistTask = runnable;
        }

        @Override
        public void run(){
            Runnable task = this.fistTask;
            while (null!=task || null!= (task=getTask())){
                try {
                    task.run();
                } finally {
                    task = null;
                }
            }
        }
    }

    public Runnable getTask(){
        try {
            return workQueue.take();
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
    }



}
